home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-15 | 56.3 KB | 1,667 lines |
- /*
- * Copyright (c) 1992 Stanford University
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the name
- * Stanford may not be used in any advertising or publicity relating to
- * the software without the specific, prior written permission of
- * Stanford.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
- * ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- */
-
- /* $Header: /Source/Media/collab/VideoObject/RCS/CVD1000Driver.c,v 1.21 92/10/02 13:58:15 drapeau Exp $ */
- /* $Log: CVD1000Driver.c,v $
- * Revision 1.21 92/10/02 13:58:15 drapeau
- * Removed code in PlayFromTo method that takes pre-roll time into account; that
- * is, the Vdeck takes about two seconds before audio can be heard with video,
- * but this code no longer tries to correct for that. A new VideoObject should
- * really be designed to take care of this type of problem.
- *
- * Revision 1.20 92/09/28 12:38:23 drapeau
- * Fixed an error in the PlayFromTo() function. The wrong variable was used
- * to hold the result of a QueryFrame() call.
- *
- * Revision 1.19 92/09/24 16:24:00 drapeau
- * Primary change was in the semantics of the PlayFromTo method. The semantics
- * have been changed: in the new case, when fromAddress == toAddress, a
- * non-blocking search has been requested; when fromAddress != 0 and
- * toAddress == 0, a blocking search has been requested. This is a different
- * interpretation than before; it was determined that it was more important to
- * give the application programmer a choice between blocking and non-blocking
- * searches than it was to have the programmer decide to search to an address
- * and continue playing from there (since this latter interpretation can be
- * emulated by a call to DevPlayFromTo(startAddress, 0) and DevPlay()).
- *
- * Also, minor cosmetic changes were made to the code for improved readability.
- *
- * Revision 1.18 92/09/04 16:42:12 drapeau
- * Modified CVD1000PlayFromTo(), case b (startAddress == 0,
- * endAddress > 0). This means to play from the current
- * position until some end address is reached, intended to be used in editing
- * situations where this is the playback deck. The driver now takes into
- * account that the deck doesn't "warm up" for a couple of seconds. So,
- * the driver now begins playback in this case two seconds before the actual
- * starting point of the edit (if the edit is less than 2 seconds from the
- * beginning of the tape, the edit will begin at time zero; this means that
- * authors should never put usable video material on, say, the first 10
- * seconds of a videotape).
- *
- * Revision 1.17 92/09/04 14:25:14 drapeau
- * Made a number of changes to improve the overall quality of the driver:
- * * Added prefix "CVD1000" to all new functions, for better code
- * encapsulation and programming practice. For example, the function
- * InputPending() is now CVD1000InputPending().
- * * Improved clarity of diagnostic messages.
- * * Major modifications to the RecordFromTo() method, to take into
- * account timing conditions between the record and playback decks.
- * For example, it is not necessary to block during the search phase
- * (searching for the start of the playback and start of the record
- * frame), but the function should block before going into insert
- * edit mode (the function makes sure that any searching is completed
- * before going into insert edit mode). Also, the function should block
- * until the complete segment has been recorded. This is one of the few
- * times that the driver blocks.
- * Also, fixed errors in the way commands were sent to the Vdeck to enable
- * segment recording. Before, a command was sent to begin recording only
- * after a delay equal to the time it would take the playback deck to play
- * the segment. The effect was that the playback deck would play the
- * segment, then the record deck would engage, thus recording nothing but
- * still frames (or empty video). Now, the command sent is to begin
- * recording immediately and to *end* after a delay time equal to the
- * length of the segment.
- * * Added functions SearchIsInProgress() and EditIsInProgress(), to check
- * the status of the Vdeck. Used by the RecordFromTo() functions.
- * * Note: this driver is still somewhat inaccurate for insert editing; as
- * written, the driver tends to make the deck record a few seconds after
- * the end of a segment. Perhaps another approach to stopping the Edit
- * Record would work better.
- *
- * Revision 1.16 92/09/02 17:11:17 drapeau
- * Added new function, CVD1000Cancel(), to send cancellation messages for
- * commands that are to be aborted. Currently not used, although the function
- * was used in intermediate development and deemed necessary to keep for
- * possible future use.
- * Also, added a few more diagnostic messages for easier debugging.
- * Also, minor cosmetic changes to conform to style guidelines and to
- * simplify the task of reading the code.
- *
- * Revision 1.15 92/09/01 17:13:34 drapeau
- * Made a number of changes:
- * * Cosmetic changes to make code more readable.
- * * Added two new methods, CVD1000Record() and CVD1000RecordFromTo(), in
- * accordance with new additions to the VideoObject.
- * * Modified CVD1000ReadAsynch() to make it less dependent on a
- * particular programming toolkit.
- * * Modified CVD1000PlayFromTo() to make more clear what each possible
- * case is. The logic was not obvious before, and did not directly
- * reflect the documentation for the VideoObject.
- * * Modified CVD1000PlayAtSpeedDir(); removed test that last speed must
- * be different from speed currently being requested. This was necessary
- * in order to make the PlayFromTo() method work, since it is independent
- * of whatever speed was last requested. The logic for determining whether
- * a PlayAtSpeedDir() really should be sent is now the responsibility of the
- * application programmer; the tools to determine whether the call should be
- * made are already in the VideoObject library (e.g., DevCalcSpeed()).
- *
- * Revision 1.14 92/08/25 16:28:52 drapeau
- * Major modifications to this driver:
- * * Re-implemented the code that interprets the VISCA protocol, especially
- * that code which reads replies from the Vdeck. In the process, greatly
- * simplified the protocol interpreter.
- * * Removed the ParseResponse() function, since it is replaced by simpler
- * routines for reading VISCA replies.
- * * Removed the CVD1000GetResponse() function, since it too is obsolete.
- * * Greatly simplified the CVD1000ReadAsynch() function, since it can now call
- * the utility function "CVD1000ReadReply()" to consume input from the Vdeck.
- * * Major changes to the CVD1000SendCode() function, to reflect simplifications
- * in the protocol interpreter. Removed an unneccesary function parameter;
- * the calling functions now fill in the submode data themselves, instead
- * of having SendCode() try to do it. SendCode() also consumes replies from
- * the Vdeck more intelligently and simply.
- * * Modified functions that call CVD1000SendCode() to take the new argument
- * scheme and command formatting into account. Also, removed calls to the
- * obsolete function CVD1000GetResponse(), since CVD1000SendCode() now
- * performs that function.
- * * Added two functions, CVD1000ReadReply() and CVD1000ReadInquiryReply(), to
- * read replies of all types from the Vdeck.
- *
- * Revision 1.13 92/08/05 16:17:30 drapeau
- * Changed octal representations of opcodes to hex, to make reading
- * easier for humans.
- *
- * Revision 1.12 92/07/30 15:30:52 drapeau
- * Several changes:
- *
- * * Re-formatted all function declarations to conform to ANSI function
- * prototype standards.
- * * Replaced hard-coded references to 30 frame-per-second frame rates with
- * new definition "FrameRate". All math is based on this definition now,
- * allowing the driver to be used in places where the frame rate is not
- * 30 fps.
- * * Improved diagnostic messages. Diagnostics now report the serial port
- * being used for the command when possible.
- *
- * Revision 1.11 92/06/17 01:00:25 drapeau
- * Changed termio usage, used more portable "termio" structure and
- * associated calls instead of "termios".
- *
- * Revision 1.10 92/06/17 00:21:02 drapeau
- * Updated copyright notice.
- *
- * Revision 1.0 92/06/17 00:16:22 drapeau
- * Initial revision
- * */
-
- #include "CVD1000Driver.h"
-
- /* Assumption : only 1 device is being controlled.
- no daisy-chain, so address assignment is not done.
- all commands use destination address 1. */
- /* Time is encoded in BCD */
-
- static char cvdrcsid[] = "$Header: /Source/Media/collab/VideoObject/RCS/CVD1000Driver.c,v 1.21 92/10/02 13:58:15 drapeau Exp $";
- OutCommand* listHead = NULL; /* Holds list of socket numbers of ACKs that have not
- been matched with COMPLETIONS, essentially resulting
- from PlayFromTo calls (can have multiple such calls
- in succession) */
- OutCommand* listTail = NULL;
- int addMode; /* Addressing mode : PlayerFrameMode (normal),
- PlayerChapterMode (chapter/index) */
- char reply[50]; /* Place into which replies are read from file descriptor */
- char command[20];
- static char diagMsg[128];
-
- int videoDisplay; /* Video Display state info (can't get this from CVD1000) */
- static VideoObject* tempObjectPtr; /* Used for the asynchronous read function */
-
-
- /* Function to add new element to list of unmatched ACKs. */
-
- void
- AddList(int socket)
- {
- OutCommand* new;
-
- new = (OutCommand*) malloc(sizeof(OutCommand));
- new->socketNum = socket;
- if (listHead == NULL)
- listHead = new;
- if (listTail)
- listTail->next = new;
- listTail = new;
- new->next = NULL;
- }
-
-
-
- /* Function to remove item with socket number = 'socket' from
- list of unmatched ACKs.
- Returns 0 if it is found, -1 otherwise */
- int
- RemoveList(int socket)
- {
- OutCommand* prev;
- OutCommand* current;
- int found = 0;
-
- prev = NULL;
- current = listHead;
-
- while ((current) && !(found))
- {
- if (current->socketNum == socket)
- {
- if (prev)
- prev->next = current->next;
- else
- listHead = current->next;
- if (listTail == current)
- listTail = prev;
- free(current);
- found = 1;
- }
- else
- {
- prev = current;
- current = current->next;
- }
- }
- if (found)
- return 0;
- else
- return -1;
- } /* end function RemoveList */
-
-
- /* Function to determine the type of reply that character c
- represents.
- Returns CVDAck, Completion, CVDError, or Unknown */
- int
- WhichReply(char c)
- {
- c = (c & ReplyMask);
- switch (c)
- {
- case '\x40':
- return CVDAck;
- case '\x50':
- return Completion;
- case '\x60':
- return CVDError;
- default:
- return CVDError;
- }
- } /* end function WhichReply */
-
-
- int CVD1000InputPending(int fd)
- {
- fd_set readfds;
- struct timeval waitTime;
- int result = 0;
- int descriptorTableSize = 0;
-
- waitTime.tv_sec = 0; /* Set up a zero-wait timeval to make select poll,... */
- waitTime.tv_usec = 0; /* ...meaning that either input is ready immediately, or not */
- FD_ZERO(&readfds); /* Initialize set of files to be checked; check no files */
- FD_SET(fd, &readfds); /* Look for input only on the file passed in as argument */
- descriptorTableSize = getdtablesize();
- result = select(descriptorTableSize, &readfds, (fd_set*)NULL,
- (fd_set*)NULL, &waitTime);
- return(result);
- } /* end function CVD1000InputPending */
-
-
-
-
- /* Sends out command in this format:
- Packet = Packet header (#defined as 'Header',
- hard-coded to send to device with address 1)
- + Message + Terminator (#defined as 'Terminator')
- Message = Message header + Message Category + Category Mode + Specifics
- */
-
- int CVD1000SendCode(VideoObject* theObject,
- char msgFormat,
- char categoryCode,
- char* specific,
- int cmdLength,
- int bytesExpected)
- {
- int numWritten;
- int counter = 0;
- int result = 0;
- char oneChar;
- char command[20];
- int numRetries = 0;
- struct termio lineAttributes;
- char oldTimeOut;
- char oldMinChars;
-
- while (CVD1000InputPending(theObject->DevConfig->fd) == 1) /* Is there data to be read from the Vdeck? */
- {
- result = CVD1000ReadReply(theObject); /* Yes, consume the data */
- }
-
- bzero(command, 4 + cmdLength); /* Set up command */
- command[0] = Header;
- command[1] = msgFormat; /* E.g., "Command Format1", "Inquiry", "Address" */
- command[2] = categoryCode; /* E.g., "Vcr", "Effects", "Interface" */
- bcopy(specific, &command[3], cmdLength);
- command[3+cmdLength] = Terminator;
-
- numWritten = write(theObject->DevConfig->fd, command, /* Send command */
- 4 + cmdLength);
- if (numWritten == (4 + cmdLength)) /* Was command packet correctly sent to the Vdeck? */
- { /* Yes, report diagnostics */
- sprintf(diagMsg, "%s :\tIn CVDSendCode, wrote %d bytes:\t::",
- theObject->DevConfig->serialPort,
- numWritten);
- PrintDiagnostics(diagMsg);
- for (counter = 0; counter < 4 + cmdLength; counter++)
- {
- oneChar = command[counter];
- sprintf(diagMsg, "%02X::", oneChar);
- PrintDiagnostics(diagMsg);
- }
- PrintDiagnostics("\n");
- }
- else /* No, an error occurred in sending the command to the Vdeck */
- {
- sprintf(diagMsg, "%s :\tWrite error.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- return -1;
- }
-
- if (msgFormat == Inq) /* Was the command an Inquiry? */
- {
- result = CVD1000ReadInquiryReply(theObject, bytesExpected);
- }
- else
- {
- result = CVD1000ReadReply(theObject);
- }
- return(result);
- } /* end function CVD1000SendCode */
-
-
-
- int CVD1000ReadInquiryReply(VideoObject* theObject,
- int bytesExpected)
- {
- int errorCat;
- int errorNum;
- int result = 0;
- int socket = 0;
- int counter = 0;
- int errorCount = 0;
- char oneChar;
- char theReply[20];
-
- sprintf(diagMsg, "%s :\t-----Entering CVD1000ReadInquiryReply.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- result = read(theObject->DevConfig->fd, theReply, 1); /* Read the 1st byte of Vdeck's reply */
- if (result < 1) /* Did the read fail? */
- return(PlayerReturnError); /* Yes, return an error code */
- if (theReply[0] != RcvHeader) /* Was the expected Vdeck header character received? */
- { /* No, an error occurred */
- sprintf(diagMsg, "%s :\tUnexpected reply from CVD1000: ::%2X::.\n",
- theObject->DevConfig->serialPort, theReply[0]);
- PrintDiagnostics(diagMsg);
- while (theReply[0] != Terminator) /* Consume any leftover characters (read until Terminator... */
- { /* ...character is encountered) */
- result = read(theObject->DevConfig->fd, theReply, 1); /* Read another byte from the Vdeck */
- if (result < 1) /* Did a read error occur? */
- break; /* Yes, get out of this while loop */
- }
- return(PlayerReturnError);
- }
- result = read(theObject->DevConfig->fd, theReply, 1); /* Read the 2nd byte of Vdeck's reply */
- if (result < 1) /* Did the read fail? */
- return(PlayerReturnError); /* Yes, return an error code */
- socket = (theReply[0] & SocketMask); /* Determine the socket number for this reply */
- sprintf(diagMsg, "%s :\tSecond byte of reply = %2X, socket is %d.\n",
- theObject->DevConfig->serialPort,
- (int)theReply[0], socket);
- PrintDiagnostics(diagMsg);
- RemoveList(socket); /* Remove socket from list */
- if (WhichReply(theReply[0]) == CVDError) /* Was an error condition returned? */
- { /* Yes */
- RemoveList(socket); /* Remove socket from list */
- result = read(theObject->DevConfig->fd, theReply, 1); /* Read the error code byte from the Vdeck */
- if (result < 1) /* Did the read fail? */
- return(PlayerReturnError); /* Yes, return an error code */
- CVD1000PrintErrorMessage((theReply[0] & ErrorCatMask), /* Decode and print the error message */
- theReply[0] & ErrorNumMask);
- result = read(theObject->DevConfig->fd, theReply, 1); /* Read the terminator byte from the Vdeck */
- return(PlayerReturnError);
- }
- else if (WhichReply(theReply[0] == Completion)) /* No, a Completion was read */
- {
- RemoveList(socket); /* Remove socket from list */
- for (counter = 0; counter < bytesExpected; counter++)
- {
- result = read(theObject->DevConfig->fd, &(reply[counter]), 1); /* Read the inquiry reply information from the Vdeck */
- if (result < 1) /* Did something go wrong with the read? */
- { /* Yes, print an error message and return an error code */
- sprintf(diagMsg, "%s :\tError in reading inquiry reply data. Bytes expected: %d, bytes received: %d\n.",
- theObject->DevConfig->serialPort, bytesExpected,
- counter);
- PrintDiagnostics(diagMsg);
- for (errorCount = 0; errorCount < counter; errorCount++) /* Print bytes received so far */
- {
- oneChar = reply[errorCount];
- sprintf(diagMsg, "%02X::", oneChar);
- PrintDiagnostics(diagMsg);
- }
- PrintDiagnostics("\n");
- return(PlayerReturnError);
- }
- }
- sprintf(diagMsg, "%s :\tReply from Inquiry is:\t::",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- for (counter = 0; counter < bytesExpected; counter++)
- {
- oneChar = reply[counter];
- sprintf(diagMsg, "%02X::", oneChar);
- PrintDiagnostics(diagMsg);
- }
- PrintDiagnostics("\n");
- if (reply[bytesExpected - 1] == Terminator) /* Sometimes the Vdeck drops a byte in its response; did... */
- { /* ...this happen? (i.e., did an error occur?) */
- return(PlayerReturnError); /* Yes, don't bother trying to read the message Terminator */
- }
- else /* No, the inquiry went okay; read the message Terminator */
- {
- result = read(theObject->DevConfig->fd, theReply, 1); /* Read the terminator byte from the Vdeck */
- if (result < 1) /* Did the read fail? */
- return(PlayerReturnError); /* Yes, return an error code */
- else
- return(PlayerOk);
- }
- } /* end else if (WhichReply... */
- } /* end function CVD1000ReadInquiryReply */
-
-
-
-
- /* Reads response from Vdeck, checking if it is an ACK, COMPLETION, or ERROR message. */
- int
- CVD1000ReadReply(VideoObject* theObject)
- {
- int errorCat;
- int errorNum;
- int result = 0;
- int socket = 0;
- char theReply[20];
-
- sprintf(diagMsg, "%s :\t-----Entering CVD1000ReadReply.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
-
- result = read(theObject->DevConfig->fd, &(theReply[0]), 1); /* Read the 1st byte of Vdeck's reply */
- if (theReply[0] != RcvHeader) /* Was the expected Vdeck header character received? */
- { /* No, an error occurred */
- sprintf(diagMsg, "%s :\tUnexpected reply from CVD1000: ::%2X::.\n",
- theObject->DevConfig->serialPort, theReply[0]);
- PrintDiagnostics(diagMsg);
- while (theReply[0] != Terminator) /* Consume any leftover characters (read until Terminator... */
- { /* ...character is encountered) */
- sprintf(diagMsg, "%s :\tTrying to consume another byte.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- result = read(theObject->DevConfig->fd, theReply, 1); /* Read another byte from the Vdeck */
- if (result < 1) /* Did a read error occur? */
- break; /* Yes, get out of this while loop */
- }
- return(PlayerReturnError);
- }
- result = read(theObject->DevConfig->fd, &(theReply[1]), 1); /* Read the 2nd byte of Vdeck's reply */
- socket = (theReply[1] & SocketMask); /* Determine the socket number for this reply */
- sprintf(diagMsg, "%s :\tSecond byte of reply = %2X, socket is %d.\n",
- theObject->DevConfig->serialPort,
- (int)theReply[1], socket);
- PrintDiagnostics(diagMsg);
- RemoveList(socket); /* Remove socket from list */
- if (WhichReply(theReply[1]) == CVDError) /* Was an error condition returned? */
- { /* Yes */
- RemoveList(socket); /* Remove socket from list */
- result = read(theObject->DevConfig->fd, theReply, 1); /* Read the error code byte from the Vdeck */
- CVD1000PrintErrorMessage((theReply[0] & ErrorCatMask), /* Decode and print the error message */
- theReply[0] & ErrorNumMask);
- result = read(theObject->DevConfig->fd, theReply, 1); /* Read the terminator byte from the Vdeck */
- return(PlayerReturnError);
- }
- else if (WhichReply(theReply[1] == CVDAck)) /* No, an ACK was read */
- {
- AddList(socket); /* Remove socket from list */
- result = read(theObject->DevConfig->fd, &(theReply[2]), 1); /* Read the terminator byte from the Vdeck */
- }
- else if (WhichReply(theReply[1] == Completion)) /* A Completion was read */
- {
- RemoveList(socket); /* Remove socket from list */
- result = read(theObject->DevConfig->fd, &(theReply[2]), 1); /* Read the terminator byte from the Vdeck */
- }
- return(PlayerOk);
- } /* end function CVD1000ReadReply */
-
-
-
- /* Asynchronous read function for reading COMPLETIONs of PlayFromTo */
- int
- CVD1000ReadAsynch(int fd)
- {
- int result = 0;
-
- result = CVD1000ReadReply(tempObjectPtr);
- SetAsynchReadFunction(NULL, fd, FeatureOff); /* Set automatic read off */
- } /* end function CVD1000ReadAsynch */
-
-
- /* Converts decimal to char in BCD */
- void
- CVD1000ConvertToBCD(int num,
- char* bcd)
- {
- char tmp1[1];
- char tmp2[1];
-
- tmp1[0] = (num/10)<<4;
- tmp2[0] = num%10;
- tmp1[0] = tmp1[0] | tmp2[0];
- bcopy(tmp1, bcd, 1);
-
- } /* end function CVD1000ConvertToBCD */
-
-
- /* Converts char in BCD to decimal */
- int
- CVD1000ConvertFromBCD(char bcd)
- {
- int tmp1;
- int tmp2;
- tmp1 = (bcd & UpperMask)>>4;
- tmp2 = bcd & LowerMask;
- return (tmp1*10 + tmp2);
- } /* end function CVD1000ConvertFromBCD */
-
-
- /* Converts time to address in frames */
- int
- CVD1000ConvertTimeToFrame(int hr,
- int min,
- int sec,
- int frame)
- {
- int address;
-
- address = FrameRate * (hr*3600 + min*60 + sec) + frame;
- return address;
- } /* end function CVD1000ConvertTimeToFrame */
-
-
- /* Converts address in frames to hr, min, sec, frames */
- void
- CVD1000ConvertFrameToTime(char* hr,
- char* min,
- char* sec,
- char* frame,
- int address)
- {
- int h;
- int s;
- int m;
- int f;
- int framesPerHour;
- int framesPerMinute;
- int framesPerSecond;
-
- framesPerHour = 3600 * FrameRate; /* 3600 = seconds per hour */
- framesPerMinute = 60 * FrameRate;
- framesPerSecond = FrameRate;
-
- h = address / framesPerHour;
- m = (address % framesPerHour) / framesPerMinute;
- s = ((address % framesPerHour) % framesPerMinute) / framesPerSecond;
- f = ((address % framesPerHour) % framesPerMinute) % framesPerSecond;
-
- CVD1000ConvertToBCD(h, hr);
- CVD1000ConvertToBCD(m, min);
- CVD1000ConvertToBCD(s, sec);
- CVD1000ConvertToBCD(f, frame);
-
- } /* end function CVD1000ConvertFrameToTime */
-
-
- int
- CVD1000Play(VideoObject* theObject)
- {
- sprintf(diagMsg, "\n%s :\tEntering CVD1000Play.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = Mode1;
- command[1] = '\x28';
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- } /* end function CVD1000Play */
-
-
- int
- CVD1000SearchFrame(VideoObject* theObject,
- int address,
- int playOn)
- {
- char sHr[1];
- char sMin[1];
- char sSec[1];
- char sFrame[1];
- int result = 0;
-
- sprintf(diagMsg, "\n%s :\tCVD1000SearchFrame, address is %d.\n",
- theObject->DevConfig->serialPort,
- address);
- PrintDiagnostics(diagMsg);
- CVD1000ConvertFrameToTime(sHr, sMin, sSec, sFrame, address);
- bzero(command, 6);
- command[0] = Search;
- command[1] = TimeCode;
- bcopy(sHr, &command[2], 1);
- bcopy(sMin, &command[3], 1);
- bcopy(sSec, &command[4], 1);
- bcopy(sFrame, &command[5], 1);
- if (playOn != 0)
- command[6] = '\x28'; /* Play */
- else
- command[6] = '\x20'; /* Still */
- return(CVD1000SendCode(theObject, Command1, Vcr, command, 7, 0));
- } /* end function CVD1000SearchFrame */
-
-
- int
- CVD1000SearchChapter(VideoObject* theObject,
- int startChap,
- int playOn)
- {
- sprintf(diagMsg, "\n%s :\tEntering CVD1000SearchChapter.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- bzero(command, 6);
- command[0] = Search;
- command[1] = ChapterCode;
- command[2] = '\x00';
- command[3] = '\x00';
- command[4] = startChap/10;
- command[5] = startChap%10;
- if (playOn)
- command[6] = '\x28'; /* Play */
- else
- command[6] = '\x20'; /* Still */
-
- CVD1000SendCode(theObject, Command1, Vcr, command, 7, 0);
- } /* end function CVD1000SearchChapter */
-
-
- int
- CVD1000SearchIndex(VideoObject* theObject,
- int theIndex,
- int dir)
- {
- sprintf(diagMsg, "\n%s :\tEntering CVD1000SearchIndex.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- bzero(command, 6);
- command[0] = Search;
- command[1] = IndexCode;
- if (dir == Forward)
- command[2] = '\x00';
- else
- command[2] = '\x40';
- command[3] = '\x00';
- command[4] = theIndex / 10;
- command[5] = theIndex % 10;
- command[6] = '\x20';
-
- CVD1000SendCode(theObject, Command1, Vcr, command, 7, 0);
- } /* end function CVD1000SearchIndex */
-
-
-
- /* Queries Vdeck to determine the type of counter being used (i.e., TimeCode or Chapter */
- int
- CVD1000QueryMedium(VideoObject* theObject,
- char* result)
- {
- int chapter = 0;
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000QueryMedium.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = '\x52';
- command[1] = '\x02';
- command[2] = '\x01';
- CVD1000SendCode(theObject, Inq, Vcr, command, 3, 1);
-
- if (((int) reply[0]) == '\x12')
- chapter = PlayerChapterMode;
- else
- chapter = PlayerFrameMode;
- return chapter;
- } /* end function CVD1000QueryMedium */
-
-
- int
- CVD1000PlayFromTo(VideoObject* theObject,
- int startAddress, /* Is 0 if play from current position */
- int endAddress, /* Denotes direction if index search */
- int speedInFramesPerSecond)
- {
- int chapterCode; /* 1 when prerecorded chapter marks exist, 0 otherwise */
- int result = 0;
- char eHr[1];
- char eMin[1];
- char eSec[1];
- char eFrame[1];
-
- sprintf(diagMsg, "\n%s :\tCVD1000PlayFromTo: from %d to %d.\n",
- theObject->DevConfig->serialPort,
- startAddress, endAddress);
- PrintDiagnostics(diagMsg);
-
- if (addMode == PlayerChapterMode)
- {
- chapterCode = CVD1000QueryMedium(theObject, NULL);
- sprintf(diagMsg, "%s :\tChapter code = %d.\n",
- theObject->DevConfig->serialPort,
- chapterCode);
- PrintDiagnostics(diagMsg);
-
- if (chapterCode == PlayerChapterMode)
- {
- if (startAddress == endAddress) /* Simple search and still */
- return(CVD1000SearchChapter(theObject, startAddress, 0));
- else if (startAddress != NULL) /* Play from specific chapter */
- {
- if (CVD1000SearchChapter(theObject, startAddress, 0) == -1)
- {
- sprintf(diagMsg, "%s :\tStart Chapter cannot be found.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- return PlayerReturnError;
- }
- else
- CVD1000PlayAtSpeedDir(theObject, speedInFramesPerSecond, Forward);
- }
- else
- CVD1000PlayAtSpeedDir(theObject, speedInFramesPerSecond, Forward); /* Play from current position */
-
- if (endAddress != NULL) /* Play till specific chapter */
- {
- bzero(command, 6);
- command[0] = ChapterCode;
- command[1] = '\x00';
- command[2] = '\x00';
- command[3] = (endAddress/10); /* 0X */
- command[4] = (endAddress%10); /* OY, where XY = Chapter no. */
- command[5] = '\x01'; /* stop */
- command[6] = '\x00';
- CVD1000SendCode(theObject, Command3, Vcr, command, 7, 0);
- tempObjectPtr = theObject; /* Set global variable "tempObjectPointer" to point to... */
- SetAsynchReadFunction(CVD1000ReadAsynch, /* ...current videoObject so async. read function can... */
- theObject->DevConfig->fd, FeatureOn); /* ...use the info in it. */
- }
- else
- return PlayerOk;
- } /* end if (chapterCode == PlayerChapterMode */
- else
- return(CVD1000SearchIndex(theObject, startAddress,
- endAddress)); /* No chapter marks, do index search instead */
- } /* end if (addMode == PlayerChapterMode */
- if (startAddress == endAddress) /* Case a: search to frame "startAddress" & still */
- { /* (non-blocking search) */
- return(CVD1000SearchFrame(theObject, startAddress, 0));
- }
-
- if ((startAddress > 0) && (endAddress == 0)) /* Case b: search to frame "startAddress" & still */
- { /* (block on completion of the search) */
- if (CVD1000SearchFrame(theObject, startAddress, 0) == PlayerReturnError)
- {
- sprintf(diagMsg, "%s :\tCVD1000PlayFromTo: Start address cannot be found.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- return(PlayerReturnError);
- }
- else
- {
- sprintf(diagMsg, "%s :\tCVD1000PlayFromTo: Waiting for search to complete.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- result = CVD1000WaitForCompletion(theObject); /* Block until search is completed */
- return(result);
- }
- } /* end Case b */
-
- if ((startAddress == 0) && (endAddress != 0)) /* Case c: play from current position (no search) until... */
- { /* ...endAddress is reached, at speedInFramesPerSecond */
- while (CVD1000SearchIsInProgress(theObject) != 0) /* Is a search currently in progress? */
- { /* Yes, wait until it has completed before going any further */
- result = CVD1000WaitForCompletion(theObject); /* Maybe this Completion is for the current search, but... */
- } /* ...maybe not; that's what the while loop is for */
- CVD1000PlayAtSpeedDir(theObject, speedInFramesPerSecond, Forward);
- result = CVD1000WaitForCompletion(theObject); /* Block until playback has begun */
- CVD1000ConvertFrameToTime((char*)&eHr, (char*)&eMin,
- (char*)&eSec, (char*)&eFrame,
- endAddress);
- bzero(command, 6);
- command[0] = TimeCode;
- bcopy(eHr, &command[1], 1);
- bcopy(eMin, &command[2], 1);
- bcopy(eSec, &command[3], 1);
- bcopy(eFrame, &command[4], 1);
- command[5] = '\x01'; /* Still */
- command[6] = '\x20';
- CVD1000SendCode(theObject, Command3, Vcr, command, 7, 0); /* Play until endAddress is reached */
- tempObjectPtr = theObject; /* Set global variable "tempObjectPointer" to point to... */
- SetAsynchReadFunction(CVD1000ReadAsynch, /* ...current videoObject so async. read function can... */
- theObject->DevConfig->fd, FeatureOn); /* ...use the info in it. */
- return(PlayerOk);
- } /* end Case c */
- if ((startAddress != 0) && (endAddress != 0) /* Case d: play from startAddress to endAddress in... */
- && (startAddress < endAddress)) /* ...speedInFramesPerSecond */
- {
- result = CVD1000QueryFrame(theObject); /* Determine where the tape is currently positioned */
- if (result != startAddress) /* If the tape is not where it should be, put it there */
- {
- CVD1000SearchFrame(theObject, startAddress, 0); /* Search to start frame */
- result = CVD1000WaitForCompletion(theObject); /* Block until search is completed */
- }
- CVD1000PlayAtSpeedDir(theObject, speedInFramesPerSecond, Forward);
- result = CVD1000WaitForCompletion(theObject); /* Block until playback has begun */
- CVD1000ConvertFrameToTime((char*)&eHr, (char*)&eMin,
- (char*)&eSec, (char*)&eFrame,
- endAddress);
- bzero(command, 6);
- command[0] = TimeCode;
- bcopy(eHr, &command[1], 1);
- bcopy(eMin, &command[2], 1);
- bcopy(eSec, &command[3], 1);
- bcopy(eFrame, &command[4], 1);
- command[5] = '\x01'; /* Still */
- command[6] = '\x20';
- CVD1000SendCode(theObject, Command3, Vcr, command, 7, 0); /* Play until endAddress is reached */
- return(PlayerOk);
- } /* end Case d */
- else
- return(PlayerReturnError);
- } /* end function CVD1000PlayFromTo */
-
-
-
- int
- CVD1000Record(VideoObject* theObject)
- {
- sprintf(diagMsg, "\n%s :\tEntering CVD1000Record.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = Mode1;
- command[1] = '\x48';
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- } /* end function CVD1000Record */
-
-
-
-
- int
- CVD1000RecordFromTo(VideoObject* theObject,
- int startAddress,
- int endAddress,
- int speedInFramesPerSecond)
- {
- int result = 0;
- int hour, minute, second, frame, tick;
- int ticksPerSecond, ticksPerFrame;
- int offsetAddress;
- char eHr[1];
- char eMin[1];
- char eSec[1];
- char eFrame[1];
- char eTick1[1];
- char eTick2[2];
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000RecordFromTo.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- sprintf(diagMsg, "%s :\tRecord from %d to %d.\n",
- theObject->DevConfig->serialPort,
- startAddress, endAddress);
- PrintDiagnostics(diagMsg);
-
- if (addMode == PlayerChapterMode) /* Cannot insert edit in chapter mode, only in frame mode */
- {
- sprintf(diagMsg, "%s :\tMust be in frame addressing mode to do insert editing.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- DisplayError("Cannot perform insert editing in chapter mode.","Please make sure deck addressing is in frame address mode.");
- return(PlayerReturnError);
- } /* end if (addMode == PlayerChapterMode */
-
- while (CVD1000SearchIsInProgress(theObject) != 0) /* Is a search currently in progress? */
- { /* Yes, wait until it has completed before going any further */
- sprintf(diagMsg, "\n%s :\tCVD1000RecordFromTo: Search still in progress, waiting.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- result = CVD1000WaitForCompletion(theObject); /* Maybe this Completion is for the current search, but... */
- } /* ...maybe not; that's what the while loop is for */
-
- if ((startAddress == 0) && (endAddress == 0)) /* Put player into insert edit mode and return successfully */
- {
- command[0] = EditCtrl;
- command[1] = '\x40'; /* Edit Rec Standby */
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- result = CVD1000WaitForCompletion(theObject); /* Block until Edit Rec Standby command has completed */
- return(PlayerOk);
- }
- if ((startAddress == 0) && (endAddress > 0)) /* Perform insert editing, until 'endAddress' is reached */
- {
- command[0] = '\x03'; /* Inquire about the current VISCA clock reading */
- CVD1000SendCode(theObject, Inq, Interface, command, 1, 7);
- bzero(command, 6); /* Format the command data */
- command[0] = reply[0]; /* Copy current VISCA time into new command data */
- command[1] = reply[1];
- command[2] = reply[2];
- command[3] = reply[3];
- command[4] = reply[4];
- command[5] = '\x05'; /* Edit Record */
- command[6] = '\x48';
- CVD1000SendCode(theObject, Command2, Vcr, command, 7, 0); /* Begin edit recording right now, at current VISCA clock */
- result = CVD1000WaitForCompletion(theObject); /* Block until Edit Record command has begun executing */
-
- CVD1000ConvertFrameToTime((char*)&eHr, (char*)&eMin, /* Format the ending time for the Vdeck's record operation */
- (char*)&eSec, (char*)&eFrame,
- endAddress);
- bzero(command, 6); /* Tell the Vdeck to record until the following... */
- command[0] = TimeCode; /* ...timecode is reached */
- bcopy(eHr, &command[1], 1);
- bcopy(eMin, &command[2], 1);
- bcopy(eSec, &command[3], 1);
- bcopy(eFrame, &command[4], 1);
- command[5] = '\x05'; /* Go into Edit Rec Standby when recording is done */
- command[6] = '\x40';
- result = CVD1000SendCode(theObject, Command3, Vcr, command, 7, 0); /* Record until endAddress is reached */
- result = CVD1000WaitForCompletion(theObject); /* Block until Edit Rec Standby command has completed */
- return(result);
- }
- } /* end function CVD1000RecordFromTo */
-
-
-
- int
- CVD1000FastForward(VideoObject* theObject)
- {
- int status = 0;
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000FastForward.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- status = CVD1000QueryStatus(theObject); /* Check if in play mode */
-
- if (status != PlayerReturnError)
- switch (status)
- {
- case PlayerStop:
- case CVD1000StopTapeTop:
- case CVD1000StopTapeEnd:
- case CVD1000StopEmergency:
- command[1] = '\x08'; /* Scan */
- break;
- default:
- command[1] = '\x2E'; /* Fast forward */
- }
- else
- {
- sprintf(diagMsg, "%s :\tResponse for fast forward is wrong.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- return PlayerReturnError;
- }
- command[0] = Mode1;
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- } /* end function CVD1000FastForward */
-
-
-
- int
- CVD1000Reverse(VideoObject* theObject)
- {
- int status = 0;
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000Reverse.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- status = CVD1000QueryStatus(theObject); /* Check if in play mode */
-
- if (status != PlayerReturnError)
- switch (status)
- {
- case PlayerStop:
- case CVD1000StopTapeTop:
- case CVD1000StopTapeEnd:
- case CVD1000StopEmergency:
- command[1] = '\x10'; /* Reverse Scan */
- break;
- default:
- command[1] = '\x3E'; /* Reverse */
- }
- else
- {
- sprintf(diagMsg, "%s :\tResponse for reverse is wrong.\n",
- theObject->DevConfig->serialPort);
- return PlayerReturnError;
- }
- command[0] = Mode1;
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- } /* end function CVD1000Reverse */
-
-
-
- /* This function will determine the closest matching speed for
- * the CVD1000 player, given a desired frame rate.
- * This function returns speeds in terms of NTSC frame rates
- * (30 frames per second), although the calculations are done
- * independent of frame rate. The return values are not generic
- * because the calling function (namely, CVD1000PlayAtSpeedDir)
- * switches on the return value, and the "switch" statement in C
- * can only use constant expressions in the "case" part of the
- * statement (i.e., there can be no "case FrameRate * 2", only
- * "case 60"). So, we arbitrarily chose NTSC frame rates as our
- * standard return values. This should not hurt the generality of the
- * rest of the driver in terms of frame rates.
- */
-
- int
- CVD1000CalcSpeed(VideoObject* theObject,
- int inputValue,
- int playMode) /* Don't care */
- {
- if (inputValue < ((FrameRate / 10) + 1)) /* Less than about 0.1 * FrameRate? */
- return 3;
- else if (inputValue < (FrameRate / 2)) /* Less than 0.5 * FrameRate? */
- return 6;
- else if (inputValue < (FrameRate + (FrameRate / 2))) /* Less than 1.5 * FrameRate? */
- return 30;
- else
- return 60;
- } /* end function CVD1000CalcSpeed */
-
-
- int
- CVD1000PlayAtSpeedDir(VideoObject* theObject,
- int speedInFramesPerSecond,
- enum Direction direction)
- {
- int convertedSpeed;
- static int lastSpeed = 0;
-
- convertedSpeed = CVD1000CalcSpeed(theObject, speedInFramesPerSecond, 0);
-
- lastSpeed = convertedSpeed;
- sprintf(diagMsg, "\n%s :\tEntering CVD1000PlayAtSpeedDir.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- if (direction == Forward)
- switch (convertedSpeed)
- {
- case 3: /* 1/10th speed */
- command[1] = '\x24';
- break;
- case 6: /* 1/5th speed */
- command[1] = '\x26';
- break;
- case 30: /* 1x speed */
- command[1] = '\x28';
- break;
- case 60: /* 2x speed */
- command[1] = '\x2A';
- break;
- default:
- sprintf(diagMsg, "%s :\tConverted speed is wrong.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- }
- else
- switch (convertedSpeed)
- {
- case 3: /* 1/10th speed reverse */
- command[1] = '\x34';
- break;
- case 6: /* 1/5th speed reverse */
- command[1] = '\x36';
- break;
- case 30: /* 1x speed reverse */
- command[1] = '\x38';
- break;
- case 60: /* 2x speed reverse */
- command[1] = '\x3A';
- break;
- default:
- sprintf(diagMsg, "%s :\tConverted speed is wrong.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- }
- command[0] = Mode1;
- return(CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0));
- } /* end function CVD1000PlayAtSpeedDir */
-
-
- int
- CVD1000Still(VideoObject* theObject)
- {
- int status = 0;
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000Still.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- status = CVD1000QueryStatus(theObject); /* Check if in play mode */
-
- command[0] = Mode1;
- if (status != PlayerReturnError)
- switch (status)
- {
- case PlayerStill:
- command[1] = '\x28'; /* Play */
- break;
- case PlayerForwardPlay:
- case PlayerReversePlay:
- case PlayerForwardFast:
- case PlayerReverseFast:
- case CVD1000ForwardSlow2:
- case CVD1000ForwardSlow1:
- case CVD1000ForwardFast1:
- case CVD1000ReverseSlow2:
- case CVD1000ReverseSlow1:
- case CVD1000ReverseFast1:
- command[1] = '\x20'; /* Still */
- break;
- default:
- return PlayerOk; /* Don't do anything */
- }
- else
- {
- sprintf(diagMsg, "%s :\tResponse for query status is wrong.\n",
- theObject->DevConfig->serialPort);
- return PlayerReturnError;
- }
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- } /* end function CVD1000Still */
-
-
-
- int
- CVD1000Step(VideoObject* theObject,
- enum Direction direction)
- {
- int result = 0;
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000Step.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = Mode1; /* Still the playback first */
- command[1] = '\x20';
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- result = CVD1000WaitForCompletion(theObject); /* Block until Still command has completed */
- command[0] = Mode2;
- if (direction == Forward)
- command[1] = '\x02';
- else
- command[1] = '\x03';
-
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- } /* end function CVD1000Step */
-
-
-
- int
- CVD1000Stop(VideoObject* theObject)
- {
- OutCommand* current;
-
- SetAsynchReadFunction(NULL, theObject->DevConfig->fd, FeatureOff); /* Set automatic read off, if it is currently on */
- sprintf(diagMsg, "\n%s :\tEntering CVD1000Stop.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- for (current = listHead; current; current = current->next) /* Clear all outstanding commands */
- {
- RemoveList(current->socketNum);
- }
- command[0] = '\x01';
- CVD1000SendCode(theObject, Command1, Interface, command, 1, 0); /* Clear the VISCA command buffer */
- command[0] = Mode1;
- command[1] = '\x00'; /* Stop */
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- } /* end function CVD1000Stop */
-
-
-
- int
- CVD1000SetDefaults(VideoObject* theObject,
- int audio,
- int addressingMode,
- int addressDisplayOnOff,
- int displayMode)
- {
- sprintf(diagMsg, "\n%s :\tEntering CVD1000SetDefaults.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- CVD1000Power(theObject, FeatureOn);
- CVD1000SetAddMode(theObject, PlayerFrameMode);
- videoDisplay = FeatureOn;
-
- } /* end function CVD1000SetDefaults */
-
-
- int /* Not implemented */
- CVD1000SetAudio(VideoObject* theObject,
- int mode)
- {
- return;
- } /* end function CVD1000SetAudio */
-
-
- int
- CVD1000SetVideo(VideoObject* theObject,
- int mode)
- {
- int result;
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000SetVideo.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- if (mode != videoDisplay) /* Only capable of toggling display, so
- execute only when mode required not the same
- as current state */
- {
- command[0] = SubCtrl;
- command[1] = '\x45';
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- videoDisplay == mode;
- return result;
- }
- } /* end function CVD1000SetVideo */
-
-
-
- int
- CVD1000SetAddMode(VideoObject* theObject,
- int mode)
- {
- addMode = mode;
- } /* end function CVD1000SetAddMode */
-
-
-
- int
- CVD1000SetAddressDisplay(VideoObject* theObject,
- int onOff,
- int mode)
- {
- sprintf(diagMsg, "\n%s :\tEntering CVD1000SetAddressDisplay.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = OSD;
- if (onOff == FeatureOff)
- command[1] = '\x00';
- else
- command[1] = '\x05'; /* Time code with chapter */
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- } /* end function CVD1000SetAddressDisplay */
-
-
-
- int
- CVD1000Eject(VideoObject* theObject)
- {
- sprintf(diagMsg, "\n%s :\tEntering CVD1000Eject.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = Mode1;
- command[1] = '\x18';
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- } /* end function CVD1000Eject */
-
-
-
- int
- CVD1000Power(VideoObject* theObject,
- int mode)
- {
- sprintf(diagMsg, "\n%s :\tEntering CVD1000Power.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = '\x01';
- CVD1000SendCode(theObject, Command1, Interface, command, 1, 0); /* Clear the VISCA command buffer */
- if (mode == FeatureOn)
- command[1] = '\x02';
- else if (mode == FeatureOff)
- command[1] = '\x03';
- else
- {
- command[0] = '\x00'; /* Toggles : need to find current state first */
- CVD1000SendCode(theObject, Inq, Vcr, command, 1, 1); /* Inquiry stores one-byte reply in "reply" array */
- if (((int) reply[0]) == '\x02')
- command[1] = '\x03';
- else if (((int) reply[0]) == '\x03')
- command[1] = '\x02';
- else
- {
- sprintf(diagMsg, "%s :\tResponse for Power inquiry is wrong : ::%2X::.\n",
- theObject->DevConfig->serialPort,
- (int)reply[0]);
- PrintDiagnostics(diagMsg);
- return PlayerReturnError;
- }
- }
- command[0] = CVDPower;
- CVD1000SendCode(theObject, Command1, Vcr, command, 2, 0);
- } /* end function CVD1000Power */
-
-
-
- int
- CVD1000QueryFrame(VideoObject* theObject)
- {
- int hr;
- int min;
- int sec;
- int frame;
- int result = PlayerOk;
- OutCommand* current;
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000QueryFrame.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = Search;
- command[1] = '\x20';
-
- result = CVD1000SendCode(theObject, Inq, Vcr, command, 2, 10); /* Returns 10 data bytes */
-
- if (result != PlayerOk) /* Did the inquiry fail? */
- { /* Yes, keep trying the inquiry until it succeeds */
- sprintf(diagMsg, "\n%s :\tTimecode inquiry failed.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = '\x01';
- CVD1000SendCode(theObject, Command1, Interface, command, 1, 0); /* Clear the VISCA command buffer */
- return(PlayerReturnError);
- }
- if (((int) reply[0]) != '\x21')
- {
- sprintf(diagMsg, "%s :\tResponse for frame inquiry is wrong.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- return(PlayerReturnError);
- }
-
- hr = CVD1000ConvertFromBCD(reply[1]);
- min = CVD1000ConvertFromBCD(reply[2]);
- sec = CVD1000ConvertFromBCD(reply[3]);
- frame = CVD1000ConvertFromBCD(reply[4]);
- return (CVD1000ConvertTimeToFrame(hr, min, sec, frame));
- } /* end function CVD1000QueryFrame */
-
-
-
- int
- CVD1000QueryChapter(VideoObject* theObject)
- {
- int chapter;
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000QueryChapter.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- if (CVD1000QueryMedium(theObject, (char*)NULL) != PlayerChapterMode)
- {
- DisplayError("There are no prerecorded chapters","on this tape");
- return PlayerReturnError;
- }
-
- command[0] = Search;
- command[1] = '\x30';
- CVD1000SendCode(theObject, Inq, Vcr, command, 2, 10); /* Inquiry returns 10 data bytes */
-
- if (((int) reply[0]) != '\x31')
- {
- sprintf(diagMsg, "%s :\tResponse for chapter inquiry is wrong.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- return PlayerReturnError;
- }
- chapter = reply[3] * 10;
- chapter += reply[4];
- return chapter;
- } /* end function CVD1000QueryChapter */
-
-
-
- int /* Not implemented */
- CVD1000QueryAudio(VideoObject* theObject)
- {
- return;
- } /* end function CVD1000QueryAudio */
-
-
-
- int
- CVD1000QueryVideo(VideoObject* theObject)
- {
- return videoDisplay;
- } /* end function CVD1000QueryVideo */
-
-
-
- int
- CVD1000QueryStatus(VideoObject* theObject)
- {
- sprintf(diagMsg, "\n%s :\tEntering CVD1000QueryStatus.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = '\x01';
- CVD1000SendCode(theObject, Inq, Vcr, command, 1, 1); /* Inquiry returns one (1) data byte */
-
- switch ((int) reply[0])
- {
- case '\x00':
- return PlayerStop;
- case '\x02':
- return CVD1000StopTapeTop;
- case '\x04':
- return CVD1000StopTapeEnd;
- case '\x06':
- return CVD1000StopEmergency;
- case '\x08':
- return PlayerForwardFast;
- case '\x10':
- return PlayerReverseFast;
- case '\x18':
- return PlayerEject;
- case '\x20':
- return PlayerStill;
- case '\x24':
- return CVD1000ForwardSlow2;
- case '\x26':
- return CVD1000ForwardSlow1;
- case '\x28':
- return PlayerForwardPlay;
- case '\x2A':
- return CVD1000ForwardFast1;
- case '\x2E':
- return PlayerForwardFast;
- case '\x34':
- return CVD1000ReverseSlow2;
- case '\x36':
- return CVD1000ReverseSlow1;
- case '\x38':
- return PlayerReversePlay;
- case '\x3A':
- return CVD1000ReverseFast1;
- case '\x3E':
- return PlayerReverseFast;
- case '\x40':
- return PlayerRecordPause;
- case '\x48':
- return PlayerRecording;
- default:
- sprintf(diagMsg, "%s :\tResponse for query status is wrong : Unrecognized status.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- return PlayerReturnError;
- } /* end switch */
- } /* end function CVD1000QueryStatus */
-
-
-
- int
- CVD1000Ping(VideoObject* theObject)
- {
- int nr;
- char response[3];
- char command[6];
-
- bzero(command, 6); /* Power on command */
- command[0] = Header;
- command[1] = '\x01';
- command[2] = '\x02';
- command[3] = '\x00';
- command[4] = '\x02';
- command[5] = Terminator;
-
- write(theObject->DevConfig->fd, command, 6);
- sprintf(diagMsg, "%s :\tSent ping...",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- nr = read(theObject->DevConfig->fd, response, 3); /* Read Ack */
- if (nr != 0)
- {
- sprintf(diagMsg, "%s :\tPing was successful.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- read(theObject->DevConfig->fd, response, 3); /* Read Completion */
- }
- else
- {
- sprintf(diagMsg, "%s :\tPing failed.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- }
- return nr;
- } /* end function CVD1000Ping */
-
-
- void CVD1000PrintErrorMessage(int errorCategory, int errorNumber)
- {
- if (errorCategory == '\x00')
- {
- switch (errorNumber)
- {
- case '\x01':
- sprintf(diagMsg, "Error type : message length error (>14 bytes).\n");
- break;
- case '\x02':
- sprintf(diagMsg, "Error type : syntax error.\n");
- break;
- case '\x03':
- sprintf(diagMsg, "Error type : command buffer full.\n");
- break;
- case '\x04':
- sprintf(diagMsg, "Error type : command cancelled.\n");
- break;
- case '\x05':
- sprintf(diagMsg, "Error type : no such socket (to be cancelled).\n");
- break;
- }
- } /* end if (errorCategory... */
- else if (errorCategory == '\x40')
- {
- switch (errorNumber)
- {
- case '\x00':
- sprintf(diagMsg, "Error type : Power off.\n");
- DisplayError("Command cannot be executed because", "power is off");
- break;
- case '\x01':
- sprintf(diagMsg, "Error type : Command failed.\n");
- break;
- case '\x02':
- sprintf(diagMsg, "Error type : Search error.\n");
- DisplayError("Unable to search address", " ");
- break;
- case '\x03':
- sprintf(diagMsg, "Error type : Condition error.\n");
- break;
- case '\x06':
- sprintf(diagMsg, "Error type : Counter type error.\n");
- break;
- case '\x07':
- sprintf(diagMsg, "Error type : Tuner error.\n");
- DisplayError("Tuner error", " ");
- break;
- case '\x08':
- sprintf(diagMsg, "Error type : Emergency stop error.\n");
- break;
- case '\x09':
- sprintf(diagMsg, "Error type : No cassette inserted.\n");
- DisplayError("No cassette inserted", "Please insert cassette into deck");
- break;
- case '\x0A':
- sprintf(diagMsg, "Error type : Register error.\n");
- break;
- case '\x0B':
- sprintf(diagMsg, "Error type : Register mode setting error.\n");
- break;
- } /* end switch (errorNumber... */
- } /* end if */
- PrintDiagnostics(diagMsg);
- return;
- } /* end function CVD1000PrintErrorMessage */
-
-
- int CVD1000Cancel(VideoObject* theObject,
- int socketNumber)
- {
- int numWritten;
- char cancelCommand[20];
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000Cancel, socket number %d.\n",
- theObject->DevConfig->serialPort, socketNumber);
- PrintDiagnostics(diagMsg);
- cancelCommand[0] = '\x2F' & socketNumber;
- numWritten = write(theObject->DevConfig->fd, cancelCommand, 1); /* Send command */
-
- if (numWritten < 1) /* Was there an error in sending the Cancel command? */
- { /* Yes, report diagnostics */
- sprintf(diagMsg, "%s :\tError sending the Cancel command.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- return(PlayerReturnError);
- }
- else
- {
- sprintf(diagMsg, "%s :\tCancelled command with socket number %d.\n",
- theObject->DevConfig->serialPort,
- socketNumber);
- }
- return(CVD1000ReadReply(theObject));
- } /* end function CVD1000Cancel */
-
-
-
- /* This function blocks until the current command has been executed. */
-
- int CVD1000WaitForCompletion(VideoObject* theObject)
- {
- int result = 0;
-
- while (CVD1000InputPending(theObject->DevConfig->fd) != 1) /* Block until Completion message is received */
- {
- result = 0;
- }
- return(CVD1000ReadReply(theObject)); /* Consume the reply for the command just completed */
- } /* end function CVD1000WaitForCompletion */
-
-
- int CVD1000SearchIsInProgress(VideoObject* theObject)
- {
- char searchResult;
-
- sprintf(diagMsg, "\n%s :\tEntering CVD1000SearchIsInProgress.\n",
- theObject->DevConfig->serialPort);
- PrintDiagnostics(diagMsg);
- command[0] = Transport; /* Transport Inquiries tell if a search is in progress */
- CVD1000SendCode(theObject, Inq, Vcr, command, 1, 7); /* Inquiry returns seven data bytes */
- searchResult = reply[1] & SearchInProgressMask; /* Second byte of reply tells whether search is in progress */
- return(searchResult); /* Non-zero return value means search is in progress */
- } /* end function CVD1000SearchIsInProgress */
-
-
- int CVD1000EditIsInProgress(VideoObject* theObject)
- {
- char editResult;
-
- command[0] = Transport; /* Transport Inquiries tell if an edit is in progress */
- CVD1000SendCode(theObject, Inq, Vcr, command, 1, 7); /* Inquiry returns seven data bytes */
- editResult = reply[1] & EditInProgressMask; /* Second byte of reply tells whether edit is in progress */
- return(editResult); /* Non-zero return value means edit is in progress */
- } /* end function CVD1000EditIsInProgress */
-